// 防止头文件被多次包含的宏守卫
#ifndef __THREAD_HPP__
#define __THREAD_HPP__

// 包含标准输入输出流库
#include <iostream>
// 包含字符串库
#include <string>
// 包含 POSIX 标准库，用于 sleep 等 (虽然这里没直接用，但头文件通常会包含)
#include <unistd.h>
// 包含功能对象库，用于 std::function
#include <functional>
// 包含 POSIX 线程库
#include <pthread.h>

// 定义命名空间，封装线程相关的类
namespace ThreadModule
{
    // 定义函数类型别名 func_t<T>
    // 这是一个模板化的别名，依赖于类型 T
    // std::function<void(T &, std::string name)> 表示一个函数对象类型，
    // 这个函数对象接受一个类型 T 的引用和一个 std::string 作为参数，并且返回 void。
    // 这是定义线程执行任务函数签名的灵活方式。
    template <typename T>
    using func_t = std::function<void(T &, std::string name)>;

    // 注释掉的 typedef 行是 C++11 之前的 typedef 函数指针语法，
    // 或者尝试为 std::function 定义别名但语法不正确。
    // std::function 的别名需要使用 using 关键字。
    // typedef std::function<void(const T&)> func_t; // 这一行被注释掉了，不影响当前代码

    // Thread<T> 类：对 pthread 线程的模板化 C++ 封装
    // T 是线程任务函数需要操作的数据类型
    template <typename T>
    class Thread
    {
    public:
        // Excute 方法：线程真正执行任务的地方
        // 这个方法是静态线程入口函数 threadroutine 调用的实际任务执行者
        void Excute()
        {
            // 可以在这里打印线程名称，用于调试 (原始代码中注释掉了)
            // std::cout << _threadname << std::endl;
            // 调用构造函数传入的线程任务函数 _func
            // 将存储的 _data 引用和 _threadname 作为参数传递给 _func
            _func(_data, _threadname);
        }

    public:
        // 构造函数：创建 Thread<T> 对象
        // 参数 func: 线程要执行的任务函数对象 (类型为 func_t<T>)
        // 参数 data: 线程任务需要操作的外部数据，以引用方式传入并存储 (_data)
        // 参数 name: 线程名称，默认为 "none-name"
        Thread(func_t<T> func, T &data, std::string name = "none-name")
            // 初始化列表，初始化成员变量
            : _func(func),       // 初始化任务函数对象
              _data(data),       // 初始化数据引用，_data 引用外部传入的 data
              _threadname(name), // 初始化线程名称
              _stop(true)        // 初始化停止标志，默认为 true (表示尚未启动或已停止的概念)
        {
            // 构造函数体为空，所有初始化在初始化列表中完成
        }

        // 静态方法 threadroutine：符合 pthread_create 要求的线程入口函数
        // pthread_create 期望一个 void* (*)(void*) 签名的函数
        // 参数 args: pthread_create 传递过来的参数，我们传递的是 this 指针 (Thread<T>* 类型)
        static void *threadroutine(void *args)
        {
            // 将传递进来的 void* 参数（实际是 Thread<T>* this 指针）转换回 Thread<T>* 类型
            Thread<T> *self = static_cast<Thread<T> *>(args);
            // 调用对象的 Excute 方法，开始执行实际的任务
            self->Excute();
            // 线程函数执行完毕，返回 nullptr 作为退出码
            return nullptr;
        }

        // Start 方法：创建并启动底层 POSIX 线程
        // 返回值：bool，表示线程创建是否成功 (true 成功，false 失败)
        bool Start()
        {
            // 调用 pthread_create 创建底层线程
            // 第一个参数: 存储新创建线程 ID (_tid) 的地址
            // 第二个参数: 线程属性 (nullptr 使用默认属性)
            // 第三个参数: 线程入口函数 (我们定义的静态成员函数 threadroutine)
            // 第四个参数: 传递给入口函数的参数 (当前 Thread<T> 对象的 this 指针)
            int n = pthread_create(&_tid, nullptr, threadroutine, this);

            // 检查 pthread_create 的返回值
            if (n == 0) // 返回 0 表示成功
            {
                // 线程创建成功，设置 _stop 标志为 false (表示线程正在运行或已启动)
                _stop = false;
                return true; // 返回成功
            }
            else // 返回非 0 表示失败
            {
                // 可以根据 n 打印错误信息
                // perror("pthread_create failed");
                return false; // 返回失败
            }
        }

        // Detach 方法：分离底层 POSIX 线程
        // 分离后的线程在结束时由系统自动回收资源，不能再被 join
        void Detach()
        {
            // 检查 _stop 标志是否为 false (通常表示线程已启动)
            // 只有已启动的线程才能被分离或等待
            if (!_stop)
            {
                // 调用 pthread_detach 分离 _tid 对应的线程
                // 这里没有检查 pthread_detach 的返回值
                pthread_detach(_tid);
            }
            // 如果 _stop 为 true (线程未启动或已标记停止)，则不执行分离
        }

        // Join 方法：等待底层 POSIX 线程结束并回收其资源
        // 只有未分离的线程才能被 join
        void Join()
        {
            // 检查 _stop 标志是否为 false (通常表示线程已启动)
            if (!_stop)
            {
                // 调用 pthread_join 等待 _tid 对应的线程结束
                // nullptr 表示不获取线程退出码
                // 这里没有检查 pthread_join 的返回值
                pthread_join(_tid, nullptr);
            }
            // 如果 _stop 为 true (线程未启动或已标记停止)，则不执行等待
        }

        // name 方法：获取线程名称
        // 返回值：线程名称字符串
        std::string name()
        {
            return _threadname;
        }

        // Stop 方法：设置 _stop 标志为 true
        // 注意：这个 Stop 方法只是简单地设置一个布尔标志。
        // 用户传入的线程任务函数 _func 需要在内部**定期检查**这个 _stop 标志的状态，
        // 并根据标志的值来决定是否提前退出循环或结束任务，实现**合作式**的线程停止。
        // 这个类本身不会强制终止线程的执行。
        void Stop()
        {
            _stop = true; // 将停止标志设为 true
        }

        // 析构函数
        // 注意：这个析构函数是空的。
        // 这意味着 Thread<T> 对象在销毁时，不会自动调用 Join 或 Detach。
        // 如果一个 Thread<T> 对象所关联的底层 pthread 线程在 Thread<T> 对象销毁时仍然处于 joinable 状态（默认），
        // 且没有被 Join，可能会导致资源泄漏。
        // 一个更鲁棒的设计可能会在析构函数中检查线程状态并根据情况自动 Join 或 Detach。
        ~Thread() {}

    private:
        pthread_t _tid;          // 底层 POSIX 线程 ID
        std::string _threadname; // 线程名称
        T &_data;                // 对外部数据的引用。这意味着线程任务直接操作外部传入的变量。
                                 // 需要确保外部数据在线程结束前一直有效。
                                 // 在多线程环境下，访问 _data 需要额外的同步机制（如互斥量）。
        func_t<T> _func;         // 线程要执行的任务函数对象，接收 T& 和 std::string 参数
        bool _stop;              // 线程的停止标志。表示线程是否应该停止执行。
                                 // 它的实际作用依赖于 _func 内部是否检查它。
    };
} // namespace ThreadModule

// 宏守卫结束
#endif